#pragma once
#include "Http.hpp"
#include <iostream>
#include <stdio.h>

#include <string>
/*
 *  sha1.h
 *
 *  Copyright (C) 1998, 2009
 *  Paul E. Jones <paulej@packetizer.com>
 *  All Rights Reserved.
 *
 *****************************************************************************
 *  $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $
 *****************************************************************************
 *
 *  Description:
 *      This class implements the Secure Hashing Standard as defined
 *      in FIPS PUB 180-1 published April 17, 1995.
 *
 *      Many of the variable names in this class, especially the single
 *      character names, were used because those were the names used
 *      in the publication.
 *
 *      Please read the file sha1.cpp for more information.
 *
 */
class SHA1
{
 
public:
 
	SHA1()
	{
		Reset();
	}

	virtual ~SHA1()
	{
		// The destructor does nothing
	}
 
	/*
	 *  Re-initialize the class
	 */
	void Reset()
	{
		Length_Low = 0;
		Length_High = 0;
		Message_Block_Index = 0;
	
		H[0] = 0x67452301;
		H[1] = 0xEFCDAB89;
		H[2] = 0x98BADCFE;
		H[3] = 0x10325476;
		H[4] = 0xC3D2E1F0;
	
		Computed = false;
		Corrupted = false;
	}
 
	/*
	*  Result
	*
	*  Description:
	*      This function will return the 160-bit message digest into the
	*      array provided.
	*
	*  Parameters:
	*      message_digest_array: [out]
	*          This is an array of five unsigned integers which will be filled
	*          with the message digest that has been computed.
	*
	*  Returns:
	*      True if successful, false if it failed.
	*
	*  Comments:
	*
	*/
	bool Result(unsigned *message_digest_array)
	{
		int i;                                  // Counter
	
		if (Corrupted)
		{
			return false;
		}
	
		if (!Computed)
		{
			PadMessage();
			Computed = true;
		}
	
		for (i = 0; i < 5; i++)
		{
			message_digest_array[i] = H[i];
		}
	
		return true;
	}
	
	/*
	*  Input
	*
	*  Description:
	*      This function accepts an array of octets as the next portion of
	*      the message.
	*
	*  Parameters:
	*      message_array: [in]
	*          An array of characters representing the next portion of the
	*          message.
	*
	*  Returns:
	*      Nothing.
	*
	*  Comments:
	*
	*/
	void Input(const unsigned char *message_array,unsigned length)
	{
		if (!length)
		{
			return;
		}
	
		if (Computed || Corrupted)
		{
			Corrupted = true;
			return;
		}
	
		while (length-- && !Corrupted)
		{
			Message_Block[Message_Block_Index++] = (*message_array & 0xFF);
	
			Length_Low += 8;
			Length_Low &= 0xFFFFFFFF;               // Force it to 32 bits
			if (Length_Low == 0)
			{
				Length_High++;
				Length_High &= 0xFFFFFFFF;          // Force it to 32 bits
				if (Length_High == 0)
				{
					Corrupted = true;               // Message is too long
				}
			}
	
			if (Message_Block_Index == 64)
			{
				ProcessMessageBlock();
			}
	
			message_array++;
		}
	}

	/*
	*  Input
	*
	*  Description:
	*      This function accepts an array of octets as the next portion of
	*      the message.
	*
	*  Parameters:
	*      message_array: [in]
	*          An array of characters representing the next portion of the
	*          message.
	*
	*  Returns:
	*      Nothing.
	*
	*  Comments:
	*
	*/
	void Input(const char  *message_array,unsigned length)
	{
		if (!length)
		{
			return;
		}
	
		if (Computed || Corrupted)
		{
			Corrupted = true;
			return;
		}
	
		while (length-- && !Corrupted)
		{
			Message_Block[Message_Block_Index++] = (*message_array & 0xFF);
	
			Length_Low += 8;
			Length_Low &= 0xFFFFFFFF;               // Force it to 32 bits
			if (Length_Low == 0)
			{
				Length_High++;
				Length_High &= 0xFFFFFFFF;          // Force it to 32 bits
				if (Length_High == 0)
				{
					Corrupted = true;               // Message is too long
				}
			}
	
			if (Message_Block_Index == 64)
			{
				ProcessMessageBlock();
			}
	
			message_array++;
		}
	}

	/*
	*  Input
	*
	*  Description:
	*      This function accepts a single octets as the next message element.
	*
	*  Parameters:
	*      message_element: [in]
	*          The next octet in the message.
	*
	*  Returns:
	*      Nothing.
	*
	*  Comments:
	*
	*/
	void Input(unsigned char message_element)
	{
		Input(&message_element, 1);
	}

	/*
	*  Input
	*
	*  Description:
	*      This function accepts a single octet as the next message element.
	*
	*  Parameters:
	*      message_element: [in]
	*          The next octet in the message.
	*
	*  Returns:
	*      Nothing.
	*
	*  Comments:
	*
	*/
	void Input(char message_element)
	{
		Input((unsigned char *)&message_element, 1);
	}

	/*
	*  operator<<
	*
	*  Description:
	*      This operator makes it convenient to provide character strings to
	*      the SHA1 object for processing.
	*
	*  Parameters:
	*      message_array: [in]
	*          The character array to take as input.
	*
	*  Returns:
	*      A reference to the SHA1 object.
	*
	*  Comments:
	*      Each character is assumed to hold 8 bits of information.
	*
	*/
	SHA1& operator<<(const char *message_array)
	{
		const char *p = message_array;
	
		while (*p)
		{
			Input(*p);
			p++;
		}
	
		return *this;
	}

	/*
	*  operator<<
	*
	*  Description:
	*      This operator makes it convenient to provide character strings to
	*      the SHA1 object for processing.
	*
	*  Parameters:
	*      message_array: [in]
	*          The character array to take as input.
	*
	*  Returns:
	*      A reference to the SHA1 object.
	*
	*  Comments:
	*      Each character is assumed to hold 8 bits of information.
	*
	*/
	SHA1& operator<<(const unsigned char *message_array)
	{
		const unsigned char *p = message_array;
	
		while (*p)
		{
			Input(*p);
			p++;
		}
	
		return *this;
	}

	/*
	*  operator<<
	*
	*  Description:
	*      This function provides the next octet in the message.
	*
	*  Parameters:
	*      message_element: [in]
	*          The next octet in the message
	*
	*  Returns:
	*      A reference to the SHA1 object.
	*
	*  Comments:
	*      The character is assumed to hold 8 bits of information.
	*
	*/
	SHA1& operator<<(const char message_element)
	{
		Input((unsigned char *)&message_element, 1);
	
		return *this;
	}

	/*
	*  operator<<
	*
	*  Description:
	*      This function provides the next octet in the message.
	*
	*  Parameters:
	*      message_element: [in]
	*          The next octet in the message
	*
	*  Returns:
	*      A reference to the SHA1 object.
	*
	*  Comments:
	*      The character is assumed to hold 8 bits of information.
	*
	*/
	SHA1& operator<<(const unsigned char message_element)
	{
		Input(&message_element, 1);
		return *this;
	}
 
private:
 
	/*
	*  ProcessMessageBlock
	*
	*  Description:
	*      This function will process the next 512 bits of the message
	*      stored in the Message_Block array.
	*
	*  Parameters:
	*      None.
	*
	*  Returns:
	*      Nothing.
	*
	*  Comments:
	*      Many of the variable names in this function, especially the single
	*      character names, were used because those were the names used
	*      in the publication.
	*
	*/
	void ProcessMessageBlock()
	{
		const unsigned K[] = {               // Constants defined for SHA-1
									0x5A827999,
									0x6ED9EBA1,
									0x8F1BBCDC,
									0xCA62C1D6
		};
		int         t;                          // Loop counter
		unsigned    temp;                       // Temporary word value
		unsigned    W[80];                      // Word sequence
		unsigned    A, B, C, D, E;              // Word buffers
	
		/*
		*  Initialize the first 16 words in the array W
		*/
		for (t = 0; t < 16; t++)
		{
			W[t] = ((unsigned)Message_Block[t * 4]) << 24;
			W[t] |= ((unsigned)Message_Block[t * 4 + 1]) << 16;
			W[t] |= ((unsigned)Message_Block[t * 4 + 2]) << 8;
			W[t] |= ((unsigned)Message_Block[t * 4 + 3]);
		}
	
		for (t = 16; t < 80; t++)
		{
			W[t] = CircularShift(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
		}
	
		A = H[0];
		B = H[1];
		C = H[2];
		D = H[3];
		E = H[4];
	
		for (t = 0; t < 20; t++)
		{
			temp = CircularShift(5, A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
			temp &= 0xFFFFFFFF;
			E = D;
			D = C;
			C = CircularShift(30, B);
			B = A;
			A = temp;
		}
	
		for (t = 20; t < 40; t++)
		{
			temp = CircularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[1];
			temp &= 0xFFFFFFFF;
			E = D;
			D = C;
			C = CircularShift(30, B);
			B = A;
			A = temp;
		}
	
		for (t = 40; t < 60; t++)
		{
			temp = CircularShift(5, A) +
				((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
			temp &= 0xFFFFFFFF;
			E = D;
			D = C;
			C = CircularShift(30, B);
			B = A;
			A = temp;
		}
	
		for (t = 60; t < 80; t++)
		{
			temp = CircularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[3];
			temp &= 0xFFFFFFFF;
			E = D;
			D = C;
			C = CircularShift(30, B);
			B = A;
			A = temp;
		}
	
		H[0] = (H[0] + A) & 0xFFFFFFFF;
		H[1] = (H[1] + B) & 0xFFFFFFFF;
		H[2] = (H[2] + C) & 0xFFFFFFFF;
		H[3] = (H[3] + D) & 0xFFFFFFFF;
		H[4] = (H[4] + E) & 0xFFFFFFFF;
	
		Message_Block_Index = 0;
	}
 
	/*
	*  PadMessage
	*
	*  Description:
	*      According to the standard, the message must be padded to an even
	*      512 bits.  The first padding bit must be a '1'.  The last 64 bits
	*      represent the length of the original message.  All bits in between
	*      should be 0.  This function will pad the message according to those
	*      rules by filling the message_block array accordingly.  It will also
	*      call ProcessMessageBlock() appropriately.  When it returns, it
	*      can be assumed that the message digest has been computed.
	*
	*  Parameters:
	*      None.
	*
	*  Returns:
	*      Nothing.
	*
	*  Comments:
	*
	*/
	void PadMessage()
	{
		/*
		*  Check to see if the current message block is too small to hold
		*  the initial padding bits and length.  If so, we will pad the
		*  block, process it, and then continue padding into a second block.
		*/
		if (Message_Block_Index > 55)
		{
			Message_Block[Message_Block_Index++] = 0x80;
			while (Message_Block_Index < 64)
			{
				Message_Block[Message_Block_Index++] = 0;
			}
	
			ProcessMessageBlock();
	
			while (Message_Block_Index < 56)
			{
				Message_Block[Message_Block_Index++] = 0;
			}
		}
		else
		{
			Message_Block[Message_Block_Index++] = 0x80;
			while (Message_Block_Index < 56)
			{
				Message_Block[Message_Block_Index++] = 0;
			}
	
		}
	
		/*
		*  Store the message length as the last 8 octets
		*/
		Message_Block[56] = (Length_High >> 24) & 0xFF;
		Message_Block[57] = (Length_High >> 16) & 0xFF;
		Message_Block[58] = (Length_High >> 8) & 0xFF;
		Message_Block[59] = (Length_High) & 0xFF;
		Message_Block[60] = (Length_Low >> 24) & 0xFF;
		Message_Block[61] = (Length_Low >> 16) & 0xFF;
		Message_Block[62] = (Length_Low >> 8) & 0xFF;
		Message_Block[63] = (Length_Low) & 0xFF;
	
		ProcessMessageBlock();
	}
 
 
	/*
	*  CircularShift
	*
	*  Description:
	*      This member function will perform a circular shifting operation.
	*
	*  Parameters:
	*      bits: [in]
	*          The number of bits to shift (1-31)
	*      word: [in]
	*          The value to shift (assumes a 32-bit integer)
	*
	*  Returns:
	*      The shifted value.
	*
	*  Comments:
	*
	*/
	inline unsigned CircularShift(int bits, unsigned word)
	{
		return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32 - bits));
	}
 
	unsigned H[5];                      // Message digest buffers
 
	unsigned Length_Low;                // Message length in bits
	unsigned Length_High;               // Message length in bits
 
	unsigned char Message_Block[64];    // 512-bit message blocks
	int Message_Block_Index;            // Index into message block array
 
	bool Computed;                      // Is the digest computed?
	bool Corrupted;                     // Is the message digest corruped?
 
};

static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
 
const std::string MAGICSTRING = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
 
class base64
{
public:
	base64()
	{}
 
	~base64()
	{}
 
	std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) 
	{
		std::string ret;
		int i = 0;
		int j = 0;
		unsigned char char_array_3[3];
		unsigned char char_array_4[4];
	
		while (in_len--) {
			char_array_3[i++] = *(bytes_to_encode++);
			if (i == 3) {
				char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
				char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
				char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
				char_array_4[3] = char_array_3[2] & 0x3f;
	
				for (i = 0; (i < 4); i++)
					ret += base64_chars[char_array_4[i]];
				i = 0;
			}
		}
	
		if (i)
		{
			for (j = i; j < 3; j++)
				char_array_3[j] = '\0';
	
			char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
			char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
			char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
			char_array_4[3] = char_array_3[2] & 0x3f;
	
			for (j = 0; (j < i + 1); j++)
				ret += base64_chars[char_array_4[j]];
	
			while ((i++ < 3))
				ret += '=';
		}
	
		return ret;
    }
private:
};






class WebsocketConnecting// Websocket协议的握手阶段
{
public:
    bool IsUpgradeToWebsocket(HttpRequest &req)// 升级成Websocket协议
    {
        // 判断是不是握手协议
        if(req._method != "GET") return false;// 不是GET方法，肯定不是协议升级
        if(req.HasHeader("Sec-WebSocket-Key") == false) return false;// 没有关键头字段
        return true;
    }

    bool WebsocketHandshake(HttpRequest &req)// 握手
    {
        _key = req.GetHeader("Sec-WebSocket-Key");// 获得key
        //DEBUG_LOG("未解析前: %s",_key.c_str());
        _key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";// 固定加上一串字符

        SHA1 sha1;
        sha1.Reset();
        sha1 << _key.c_str();// SHA1解码
        unsigned int message_digest[5];

        sha1.Result(message_digest);
        for (int i = 0; i < 5; i++) {
            message_digest[i] = htonl(message_digest[i]);
        }
        base64 base;
        _key = base.base64_encode(reinterpret_cast<const unsigned char*>(message_digest),20);// base64编码
        //DEBUG_LOG("解析后: %s",_key.c_str());
}

   void SendWebsocketResponse(const PtrConnection &conn,HttpRequest &req)// 发送Websocket升级响应
    {
        HttpResponse resp(101);
        resp._body = "测试";
        if(resp.HasHeader("Connection") == false)
            resp.SetHeader("Connection","Upgrade");
        if(resp.HasHeader("Upgrade") == false)
            resp.SetHeader("Upgrade","websocket");
        if(resp.HasHeader("Sec-WebSocket-Accept") == false)
            resp.SetHeader("Sec-WebSocket-Accept",_key);

        // 组织响应字符串
        std::string resp_str;
        resp_str += req._version + " " + std::to_string(resp._statu) + " " + Util::StatuDesc(resp._statu) + "\r\n";// 响应行
        for(auto &head:resp._headers)// 响应头
        {
            resp_str += head.first + ": " + head.second + "\r\n";
        }
        resp_str += "\r\n";// 空行
        conn->Send(resp_str.c_str(),resp_str.size());
    }
public:
    std::string _key;
};

class WebsocketContext// WebSocket上下文
{
private:
    uint64_t readBigEndianUint64(const unsigned char* data) // 读取后8八位数据
    {
        uint64_t val = 0;
        for (int i = 0; i < 8; i++)
        {
            val <<= 8;// 左移八位得到正确的小端值
            val |= static_cast<uint64_t>(data[i]);// 合并
        }
        return val;
    }

    void applyMask(std::vector<unsigned char>& payloadData, const std::vector<unsigned char>& maskKey) // 提取有效载荷
    {
        size_t maskKeySize = maskKey.size();
        size_t payloadSize = payloadData.size();
        for (size_t i = 0; i < payloadSize; i++) 
        {
            payloadData[i] = payloadData[i] ^ maskKey[i % maskKeySize];
        }
    }
public:
    WebsocketContext()
        :_payload_length(0),_mask(false),_maskkey(4)
    {}

    ~WebsocketContext()
    {}

    void ParseFrame(Buffer *buf)// 解析数据帧
    {
        if(buf->ReadAbleSize() < 2) return;// 如果可读不足2字节，那么就无法后续处理

        std::basic_string<unsigned char> str = buf->ReadAsUnsignedChar(buf->ReadAbleSize());// 获取数据帧
        _mask = str[1] & 0x80;// 是否有掩码
        _payload_length = str[1] & 0x7f;// 计算有效载荷长度

        size_t headerLength = 2;// 最小数据帧头长度(假设)
        if (_payload_length == 126)// 如果有效载荷长度为126，有效长度取后两个字节
        {
            _payload_length = ntohs(*(uint16_t *)(&str[2]));// 后两个个大端字节序，转主机字节序。注意是整数而非字符
            headerLength = 4;
        }
        else if (_payload_length == 127) // 如果有效载荷长度为127，就要读取后八个字节的数作为有效长度
        {
            _payload_length = readBigEndianUint64(&str[2]);
            headerLength = 10;
        }

        std::vector<unsigned char> maskKey;
        if (_mask) // 如果数据帧设置了掩码，那么就读取掩码出来
        {
            maskKey = { str[headerLength], str[headerLength + 1],str[headerLength + 2], str[headerLength + 3] };
            headerLength += 4;
        }

        // 有效载荷的起始位置到结束位置拷贝出来
        std::vector<unsigned char> payloadData(str.begin() + headerLength, str.begin() + headerLength + _payload_length);
        if (_mask) 
        {
            applyMask(payloadData, maskKey);// 提取有效载荷
        }

        std::string payloadString(payloadData.begin(), payloadData.end());
        _payload = payloadString;

        buf->OffsetReader(headerLength + _payload_length);
    }

    int64_t GetPayloadLength() {return _payload_length;}// 返回有效载荷长度

    std::string &GetPayload() {return _payload;}// 获取有效载荷

    std::string ConvertWebsocketMessage(const std::string &payload)// 将要发送的信息转换成Websocket数据帧
    {
        std::string frame;
    
        // 添加帧头
        uint8_t opcode = 0x81; // 文本帧
        frame += opcode;
        
        // 添加负载长度
        uint64_t payloadLength = payload.size();
        if (payloadLength < 126) 
        {
            frame += static_cast<uint8_t>(payloadLength);
        } else if (payloadLength < 65536) 
        {
            frame += static_cast<uint8_t>(126);
            frame += static_cast<uint8_t>(payloadLength >> 8);
            frame += static_cast<uint8_t>(payloadLength & 0xFF);
        } else 
        {
            frame += static_cast<uint8_t>(127);
            frame += static_cast<uint8_t>((payloadLength >> 56) & 0xFF);
            frame += static_cast<uint8_t>((payloadLength >> 48) & 0xFF);
            frame += static_cast<uint8_t>((payloadLength >> 40) & 0xFF);
            frame += static_cast<uint8_t>((payloadLength >> 32) & 0xFF);
            frame += static_cast<uint8_t>((payloadLength >> 24) & 0xFF);
            frame += static_cast<uint8_t>((payloadLength >> 16) & 0xFF);
            frame += static_cast<uint8_t>((payloadLength >> 8) & 0xFF);
            frame += static_cast<uint8_t>(payloadLength & 0xFF);
        }
        
        // 添加负载数据
        frame += payload;
        return std::move(frame);// 返回数据帧
    }
private:
    uint64_t _payload_length;// 有效载荷的长度
    bool _mask;// 是否设置了掩码
    std::vector<uint8_t> _maskkey;// 掩码内容
    std::string _payload;// 有效载荷内容
    std::weak_ptr<Connection> _conn;
};

#define DEFAULT_TIMEOUT 120// 默认定时时间，120s
class WebsocketServer
{
private:    
    using Handler = std::function<void(const HttpRequest &,HttpResponse *)>;// 回调函数
    using Handlers = std::vector<std::pair<std::regex,Handler>>;// 保存Handler的容器
    using WebsocketHandler = std::function<void (const PtrConnection &)>;// Websocket的回调函数

    void OnConnected(const PtrConnection &conn)// 连接建立成功后的回调函数
    {
        conn->SetContext(HttpContext());// 给Connection对象一个协议上下文
        //DEBUG_LOG("%d号连接连接成功！并且设置了上下文！",conn->GetFd());
    }

    void ErrorHandler(const HttpRequest &req,HttpResponse *resp)// 错误处理，响应一个HTML页面即可
    {
        std::string body;
        body += "<html>";
        body += "<head>";
        body += "<meta http-equiv='Content-Type' content='text/html;charset=utf-8'>";
        body += "</head>";
        body += "<body>";
        body += "<h1>";
        body += std::to_string(resp->_statu);
        body += " ";
        body += Util::StatuDesc(resp->_statu);
        body += "</h1>";
        body += "</body>";
        body += "</html>";
        resp->SetContent(body,"text/html");// 将响应正文设置到resp中
    }
    
    void WriteResponse(const PtrConnection &conn,const HttpRequest &req,HttpResponse &resp)// 发送响应信息
    {
        if(req.Close() == true)// 如果是短连接，就设置短连接的头部
            resp.SetHeader("Connection","close");
        else // 长连接就设置长连接的头部
            resp.SetHeader("Connection","keep-alive");
        
        if(resp._body.empty() == false && resp.HasHeader("Content-Length") == false)// 如果没有正文长度字段
            resp.SetHeader("Content-Length",std::to_string(resp._body.size()));
        if(resp._body.empty() == false && resp.HasHeader("Content-Type") == false)// 如果没有正文类型字段
            resp.SetHeader("Content-Type","application/octet-stream");
        if(resp._redirect_flag == true)// 如果设置了重定向
            resp.SetHeader("Location",resp._redirect_url);

        // 组织响应字符串
        std::string resp_str;
        resp_str += req._version + " " + std::to_string(resp._statu) + " " + Util::StatuDesc(resp._statu) + "\r\n";// 响应行
        for(auto &head:resp._headers)// 响应头
        {
            resp_str += head.first + ": " + head.second + "\r\n";
        }
        resp_str += "\r\n";// 空行
        resp_str += resp._body;// 正文
        conn->Send(resp_str.c_str(),resp_str.size());
    }

    bool IsFileHandler(const HttpRequest &req)// 判断一个HTTP请求是否是静态资源请求
    {
        if(_basedir.empty()) return false;// 如果没有设置静态资源根目录
        if(req._method != "GET" && req._method != "HEAD") return false;// 如果不是GET或HEAD方法
        if(Util::ValidPath(req._path) == false) return false;// 如果不是一个有效的请求路径

        std::string req_path = _basedir + req._path;
        if(req._path.back() == '/') req_path += "index.html";// 如果请求的资源是一个目录
        if(Util::IsRegular(req_path) == false) return false;// 请求路径和静态资源根目录合并后依然不是一个合法路径
        return true;
    }

    void FileHandler(const HttpRequest &req,HttpResponse *resp)// 处理静态资源请求
    {
        std::string req_path = _basedir + req._path;
        if(req._path.back() == '/') req_path += "index.html";
        bool ret = Util::ReadFile(req_path,&resp->_body);// 将HTTP请求当中的指定的路径中的资源读取到响应的正文当中
        if(ret == false) return;
        std::string mime = Util::ExtMime(req_path);// 根据请求资源的后缀名获得mime，以填充响应头部
        resp->SetHeader("Content-Type",mime);
    }

    void Dispatcher(HttpRequest &req,HttpResponse *resp,Handlers &handlers)// 功能性请求的处理
    {
        // 在对应请求方法的回调函数容器中，查找是否有对应的处理函数
        for(auto &handler:handlers)
        {
            const std::regex &re = handler.first;
            const Handler &functor = handler.second;
            bool ret = std::regex_match(req._path,req._mathes,re);
            if(ret == false) continue;
            return functor(req,resp);
        }
        resp->_statu = 404;
    }

    void Route(HttpRequest &req,HttpResponse *resp)
    {
        if(IsFileHandler(req) == true)
        {
            FileHandler(req,resp);
            return;
        }

        // 如果不是静态资源请求，那就是有别的任务
        if(req._method == "GET" || req._method == "HEAD")
            return Dispatcher(req,resp,_get_route);
        else if(req._method == "POST")
            return Dispatcher(req,resp,_post_route);
        else if(req._method == "PUT")
            return Dispatcher(req,resp,_put_route);
        else if(req._method == "DELETE")
            return Dispatcher(req,resp,_delete_route);
        resp->_statu = 405;
    }

    void HandShake(const PtrConnection &conn,Buffer *buf)// 正常接收HTTP请求。如果有协议握手，就处理握手
    {
        while(buf->ReadAbleSize() > 0)// 如果缓冲区当中的可读数据一直存在，那么就一直进行数据读取
        {
            HttpContext *context = conn->GetContext()->get<HttpContext>();// 获取连接的协议上下文
            context->RecvHttpRequest(buf);// 从buf当中读取HTTP请求
            HttpRequest &req = context->GetRequest();// 读取完毕之后，拿到请求
            HttpResponse resp(context->RespStatu());// 构造出响应对象

            if(context->RespStatu() >= 400)// 响应状态码是有错误的
            {
                ErrorHandler(req,&resp);// 返回一个错误页面
                WriteResponse(conn,req,resp);// 发送响应
                context->Reset();// 重置上下文
                buf->OffsetReader(buf->ReadAbleSize());
                conn->Shutdown();// 关闭连接
                return;
            }

            if(context->RecvStatu() != RECV_HTTP_OVER)
            {
                return;// 如果HTTP请求还没有读完，说明不能处理，因为请求不完整
            }

            bool ret = _ws_judge.IsUpgradeToWebsocket(req);
            if(ret == true)// 如果是Websocket握手
            {
                _ws_judge.WebsocketHandshake(req);// SHA1和base64编码
                _ws_judge.SendWebsocketResponse(conn,req);// 返回一次握手，websocket连接建立成功
                // 切换协议
                // conn->SetMessgageCallback(std::bind(&WebsocketServer::OnMessage,this,std::placeholders::_1,std::placeholders::_2));
                // conn->SetContext(WebsocketContext());
                conn->Upgrade(WebsocketContext(),nullptr,
                std::bind(&WebsocketServer::OnMessage,this,std::placeholders::_1,std::placeholders::_2),
                nullptr,nullptr);
                return;
            }

            Route(req,&resp);
            WriteResponse(conn,req,resp);
            context->Reset();// 发送完毕之后重置上下文
            if(resp.Close() == true) conn->Shutdown();
        }
    }

    void OnMessage(const PtrConnection &conn,Buffer *buf)// 协议升级之后，该函数成为读事件触发后的回调函数
    {
        WebsocketContext *context = conn->GetContext()->get<WebsocketContext>();// 获取连接的协议上下文
        context->ParseFrame(buf);// 解析数据帧

        if(_message_callback) _message_callback(conn);// 如果上层设置了回调
    }

public:
    WebsocketServer(int port)
        :_server(port)
    {
        _server.SetConnectedCallback(std::bind(&WebsocketServer::OnConnected,this,std::placeholders::_1));
        _server.SetMessgageCallback(std::bind(&WebsocketServer::HandShake,this,std::placeholders::_1,std::placeholders::_2));
    }

    void SetBaseDir(const std::string &path)// 设置静态资源根目录
    {
        if(Util::IsDirectory(path) == false) abort();// 如果设置的根目录不是一个合法的路径
        _basedir = path;
    }

    void Get(const std::string &pattern,const Handler &handler)// 设置GET方法的回调函数
    {
        _get_route.push_back(std::make_pair(std::regex(pattern),handler));
    }

    void Post(const std::string &pattern,const Handler &handler)// 设置POST方法的回调函数
    {
        _post_route.push_back(std::make_pair(std::regex(pattern),handler));
    }

    void Put(const std::string &pattern,const Handler &handler)// 设置PUT方法的回调函数
    {
        _put_route.push_back(std::make_pair(std::regex(pattern),handler));
    }

    void Delete(const std::string &pattern,const Handler &handler)// 设置DELETE方法的回调函数
    {
        _delete_route.push_back(std::make_pair(std::regex(pattern),handler));
    }

    void SetThreadCount(int count)// 设置线程数量
    {
        _server.SetThreadCount(count);
    }

    void Start()// 启动HTTP服务器
    {
        _server.Start();
    }

    void SetWebsocketMessageCallback(const WebsocketHandler &cb) {_message_callback = cb;}

	void StartInactiveBroken(int timeout)// 设置非活跃连接多久后关闭
	{
		_server.EnableInactiveRelease(timeout);
	}
private:  
    Handlers _get_route;// GET方法的回调函数容器
    Handlers _post_route;// POST方法的回调函数容器
    Handlers _put_route;// PUT方法的回调函数容器
    Handlers _delete_route;// DELETE方法的回调函数容器
    std::string _basedir;// 静态资源根目录
    TcpServer _server;// 网络库组件 
    WebsocketConnecting _ws_judge;// 判断对象
    
    WebsocketHandler _message_callback;// 有数据帧到来的回调函数
};